package com.bawan.vims.dao.impl;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import com.bawan.vims.dao.IBaseDao;
import com.google.common.base.Preconditions;

/**
 * <p> Title        : BaseDao.java </p>
 * <p> Description	: BaseDao.java </p>
 * <p> Copyright	: Copyright (c) 2015 by FITT</p>
 * <p> Author 		: JOCHEN ZHENG </p>
 * <p> Create		: 2015-1-5 11:31:52 </p> 
 * <p> version 		: 1.0 </p>
 * @param <T>
 */
@Repository("baseDao")
public class BaseDaoImpl<T extends Serializable> implements IBaseDao<T> {
	private static final Logger logger = LoggerFactory.getLogger(BaseDaoImpl.class);

	private Class<T> clazz;

	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	
	protected final void setClazz(final Class<T> clazz) {
		this.clazz = Preconditions.checkNotNull(clazz);
	}

	public final Session getSession() {
		return sessionFactory.getCurrentSession();
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		return getSession().createQuery("from " + clazz.getName()).list();
	}

	public boolean save(T entity) {
		boolean result = false;
		try {
			Preconditions.checkNotNull(entity);
			getSession().saveOrUpdate(entity);
			result = true;
		} catch (Exception e) {
			logger.error(this.getClassNameAndMethod() + " occurred error:" + e.getMessage(), e);
			result = false;
		}
		return result;
	}

	public boolean delete(T entity) {
		boolean result = false;
		try {
			Preconditions.checkNotNull(entity);
			getSession().delete(entity);
			result = true;
		} catch (Exception e) {
			logger.error(this.getClassNameAndMethod() + " occurred error:" + e.getMessage(), e);
			result = false;
		}
		return result;
	}

	public boolean update(T entity) {
		boolean result = false;
		try {
			Preconditions.checkNotNull(entity);
			getSession().update(entity);
			result = true;
		} catch (Exception e) {
			logger.error(this.getClassNameAndMethod() + " occurred error:" + e.getMessage(), e);
			result = false;
		}
		return result;
	}
	
    public final boolean deleteById(final Serializable id) {
         final T entity = findById(id);
         Preconditions.checkNotNull(entity);
         return delete(entity);
    }

	@SuppressWarnings("unchecked")
	public T findById(final Serializable id) {
		return (T) getSession().get(clazz, id);
	}

	public Map<String, Object> queryForMap(T entity) {
		return new HashMap<String, Object>();
	}
	
	protected String getClassNameAndMethod(){
		StackTraceElement[] stacks = new Throwable().getStackTrace();    
        StringBuilder sb=new StringBuilder();
        sb.append("[" ).append(this.getClass().getSimpleName()).append(".").append(stacks[1].getMethodName()).append("]  ");
        return sb.toString();
	}
}
